package com.example.shop.common.util;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;

/**
 * http连接帮助类
 *
 * 例如POST请求报文：
 * POST http://www.example.com HTTP/1.1
 * Content-Type:multipart/form-data; boundary=分隔符
 *
 * --分隔符
 * Content-Disposition: form-data; "name"=123agbcd
 *
 * title
 * --分隔符
 * Content-Disposition: form-data; name="file"; filename="chrome.png"
 * Content-Type: image/png
 *
 * PNG ... content of chrome.png ...
 * --分隔符--
 */
public class HttpURLConnectionHelper {
    /**
     * 当content-type为multipart/form-data类型时，需要用boundary指定分隔符。
     * 所以boundary后面跟的随机数，就是分隔符，后端就是通过解析到boundary的值作为分隔符来分隔参数的
     */
    //分隔符
    private static  String boundaryString;
    private byte[] responseBody=null;
    private int responseState;
    private HttpURLConnection connection=null;
    static {
        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        for(int i = 0; i < 16; ++i) {
            sb.append("AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789_-".charAt(random.nextInt("AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789_-".length())));
        }
        boundaryString=sb.toString();
    }

    public HttpURLConnectionHelper(URL url) throws IOException {
        connection= (HttpURLConnection) url.openConnection();
    }

    /**
     * POST方式的请求连接，默认的请求头信息设置
     */
    public void DefaultPostSetHeader(){
        try {
            //设置请求的方式
            connection.setRequestMethod("POST");
            //发送的请求的所有数据都不许被浏览器缓存
            connection.setUseCaches(false);
            //如果为true，则可以从连接中拿到输入流
            connection.setDoInput(true);
            //如果为true，则可以从tcp连接中拿到输出流
            connection.setDoOutput(true);
            //设置请求头参数
            connection.setRequestProperty("accept", "*/*");
            //指定传输数据为二进制数据，这样就可以传输任意东西。比如：文本、图片、音乐等
            connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundaryString);
            /**
             *  创建连接的过程需要消耗资源和时间,为了减少资源消耗，缩短响应时间，就需要重用连接。
             *  因此应该通知对方这个请求响应完成后不要关闭，下一次咱们还用这个请求继续交流
             */
            connection.setRequestProperty("connection", "Keep-Alive");
        } catch (ProtocolException e) {
            e.printStackTrace();
        }
    }

    /**
     * 设置请求参数(表单中普通字段)
     * @param general
     * @throws IOException
     */
    public void setRequestGeneralParameters(Map<String,String> general) throws IOException {
        String requestMethod = connection.getRequestMethod();
        setPostRequestParameters(general,null);
    }





    /**
     * 设置请求参数(表单中普通字段、文件字段)
     * @param general 存放着表单普通字段的键值对
     * @param filesParameters 存放着表单文件字段的键值对
     */
    public void setPostRequestParameters(Map<String,String> general, Map<String, byte[]> filesParameters) throws IOException {
        DataOutputStream out= new DataOutputStream(connection.getOutputStream());
        out.writeBytes("\r\n");
        if(general!=null){
            Iterator<Map.Entry<String, String>> iterator = general.entrySet().iterator();
            while(iterator.hasNext()){
                Map.Entry<String, String> entry = iterator.next();
                String key = entry.getKey();
                String value = entry.getValue();
                //参数的分隔符
                out.writeBytes("--" + boundaryString + "\r\n");
                //参数的名
                out.writeBytes("Content-Disposition: form-data; name=\"" + key + "\"\r\n");
                out.writeBytes("\r\n");
                //参数值
                out.writeBytes(value + "\r\n");
            }
        }
        //文件字段
        if(filesParameters!=null){
            Iterator<Map.Entry<String, byte[]>> iterator = filesParameters.entrySet().iterator();
            while(iterator.hasNext()){
                Map.Entry<String, byte[]> entry = iterator.next();
                String key = entry.getKey();
                byte[] value = entry.getValue();
                out.writeBytes("--" + boundaryString + "\r\n");
                out.writeBytes("Content-Disposition: form-data; name=\"" + key
                        + "\"; filename=\"" + " " + "\"\r\n");
                out.writeBytes("\r\n");
                out.write(value);
                out.writeBytes("\r\n");
            }
        }
        out.writeBytes("--" + boundaryString + "--" + "\r\n");
        out.writeBytes("\r\n");
        out.flush();
        out.close();
    }

    /**
     * 进行发送连接请求
     * @throws IOException
     */
    public void connect() throws IOException {
        connection.connect();
        InputStream ins=null;
        //获取本次请求的响应状态码，并进行保存
        responseState=connection.getResponseCode();
        if(responseState==HttpURLConnection.HTTP_OK){
            ins = connection.getInputStream();
        }else{
            ins = connection.getErrorStream();
        }
        ByteArrayOutputStream responseBodyBuffer = new ByteArrayOutputStream();
        byte[] buff = new byte[10240];
        int len;
        while((len = ins.read(buff)) != -1){
            responseBodyBuffer.write(buff, 0, len);
        }
        responseBody = responseBodyBuffer.toByteArray();

        //====================================================================================测试专用
        System.out.println(new String(responseBody, StandardCharsets.UTF_8));
        ins.close();
    }

    public HttpURLConnection getConnection() {
        return connection;
    }

    public byte[] getResponseBody(){
        return responseBody;
    }

    public int getResponseState() {
        return responseState;
    }
}
